﻿using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using HslCommunication.Core.Net;
using HslCommunication.LogNet;

namespace HslCommunication.Enthernet
{
	/// <summary>
	/// Udp网络的服务器端类，您可以使用本类构建一个简单的，高性能的udp服务器，接收来自其他客户端的数据，当然，您也可以自定义返回你要返回的数据<br />
	/// Server-side class of Udp network. You can use this class to build a simple, high-performance udp server that receives data from other clients. Of course, you can also customize the data you want to return.
	/// </summary>
	// Token: 0x02000102 RID: 258
	public class NetUdpServer : NetworkServerBase
	{
		/// <summary>
		/// 获取或设置一次接收时的数据长度，默认2KB数据长度
		/// </summary>
		// Token: 0x17000500 RID: 1280
		// (get) Token: 0x06001571 RID: 5489 RVA: 0x0006F2B1 File Offset: 0x0006D4B1
		// (set) Token: 0x06001572 RID: 5490 RVA: 0x0006F2B9 File Offset: 0x0006D4B9
		public int ReceiveCacheLength { get; set; } = 2048;

		/// <inheritdoc />
		// Token: 0x06001573 RID: 5491 RVA: 0x0006F2C4 File Offset: 0x0006D4C4
		public override void ServerStart(int port)
		{
			bool flag = !base.IsStarted;
			if (flag)
			{
				this.CoreSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
				this.CoreSocket.Bind(new IPEndPoint(IPAddress.Any, port));
				this.RefreshReceive();
				ILogNet logNet = base.LogNet;
				if (logNet != null)
				{
					logNet.WriteInfo(this.ToString(), StringResources.Language.NetEngineStart);
				}
				base.IsStarted = true;
			}
		}

		/// <inheritdoc />
		// Token: 0x06001574 RID: 5492 RVA: 0x0006F338 File Offset: 0x0006D538
		protected override void CloseAction()
		{
			this.AcceptString = null;
			this.AcceptByte = null;
			base.CloseAction();
		}

		/// <summary>
		/// 重新开始接收数据
		/// </summary>
		/// <exception cref="T:System.ArgumentNullException"></exception>
		// Token: 0x06001575 RID: 5493 RVA: 0x0006F350 File Offset: 0x0006D550
		private void RefreshReceive()
		{
			AppSession appSession = new AppSession();
			appSession.WorkSocket = this.CoreSocket;
			appSession.UdpEndPoint = new IPEndPoint(IPAddress.Any, 0);
			appSession.BytesContent = new byte[this.ReceiveCacheLength];
			this.CoreSocket.BeginReceiveFrom(appSession.BytesContent, 0, this.ReceiveCacheLength, SocketFlags.None, ref appSession.UdpEndPoint, new AsyncCallback(this.AsyncCallback), appSession);
		}

		// Token: 0x06001576 RID: 5494 RVA: 0x0006F3C4 File Offset: 0x0006D5C4
		private void AsyncCallback(IAsyncResult ar)
		{
			AppSession appSession = ar.AsyncState as AppSession;
			bool flag = appSession != null;
			if (flag)
			{
				try
				{
					int num = appSession.WorkSocket.EndReceiveFrom(ar, ref appSession.UdpEndPoint);
					this.RefreshReceive();
					bool flag2 = num >= 32;
					if (flag2)
					{
						bool flag3 = base.CheckRemoteToken(appSession.BytesContent);
						if (flag3)
						{
							appSession.IpEndPoint = (IPEndPoint)appSession.UdpEndPoint;
							int num2 = BitConverter.ToInt32(appSession.BytesContent, 28);
							bool flag4 = num2 == num - 32;
							if (flag4)
							{
								byte[] array = new byte[32];
								byte[] array2 = new byte[num2];
								Array.Copy(appSession.BytesContent, 0, array, 0, 32);
								bool flag5 = num2 > 0;
								if (flag5)
								{
									Array.Copy(appSession.BytesContent, 32, array2, 0, num2);
								}
								array2 = HslProtocol.CommandAnalysis(array, array2);
								int protocol = BitConverter.ToInt32(array, 0);
								int customer = BitConverter.ToInt32(array, 4);
								this.DataProcessingCenter(appSession, protocol, customer, array2);
							}
							else
							{
								ILogNet logNet = base.LogNet;
								if (logNet != null)
								{
									logNet.WriteWarn(this.ToString(), string.Format("Should Rece：{0} Actual：{1}", BitConverter.ToInt32(appSession.BytesContent, 4) + 8, num));
								}
							}
						}
						else
						{
							ILogNet logNet2 = base.LogNet;
							if (logNet2 != null)
							{
								logNet2.WriteWarn(this.ToString(), StringResources.Language.TokenCheckFailed);
							}
						}
					}
					else
					{
						ILogNet logNet3 = base.LogNet;
						if (logNet3 != null)
						{
							logNet3.WriteWarn(this.ToString(), string.Format("Receive error, Actual：{0}", num));
						}
					}
				}
				catch (ObjectDisposedException)
				{
				}
				catch (Exception ex)
				{
					ILogNet logNet4 = base.LogNet;
					if (logNet4 != null)
					{
						logNet4.WriteException(this.ToString(), StringResources.Language.SocketEndReceiveException, ex);
					}
					this.RefreshReceive();
				}
				finally
				{
				}
			}
		}

		/// <summary>
		/// 数据处理中心
		/// </summary>
		/// <param name="session">会话信息</param>
		/// <param name="protocol">暗号</param>
		/// <param name="customer"></param>
		/// <param name="content"></param>
		// Token: 0x06001577 RID: 5495 RVA: 0x0006F5EC File Offset: 0x0006D7EC
		private void DataProcessingCenter(AppSession session, int protocol, int customer, byte[] content)
		{
			bool flag = protocol == 1002;
			if (flag)
			{
				Action<AppSession, NetHandle, byte[]> acceptByte = this.AcceptByte;
				if (acceptByte != null)
				{
					acceptByte(session, customer, content);
				}
			}
			else
			{
				bool flag2 = protocol == 1001;
				if (flag2)
				{
					string @string = Encoding.Unicode.GetString(content);
					Action<AppSession, NetHandle, string> acceptString = this.AcceptString;
					if (acceptString != null)
					{
						acceptString(session, customer, @string);
					}
				}
			}
		}

		/// <summary>
		/// 向指定的通信对象发送字符串数据
		/// </summary>
		/// <param name="session">通信对象</param>
		/// <param name="customer">用户的指令头</param>
		/// <param name="str">实际发送的字符串数据</param>
		// Token: 0x06001578 RID: 5496 RVA: 0x0006F65A File Offset: 0x0006D85A
		public void SendMessage(AppSession session, int customer, string str)
		{
			this.SendBytesAsync(session, HslProtocol.CommandBytes(customer, base.Token, str));
		}

		/// <summary>
		/// 向指定的通信对象发送字节数据
		/// </summary>
		/// <param name="session">连接对象</param>
		/// <param name="customer">用户的指令头</param>
		/// <param name="bytes">实际的数据</param>
		// Token: 0x06001579 RID: 5497 RVA: 0x0006F671 File Offset: 0x0006D871
		public void SendMessage(AppSession session, int customer, byte[] bytes)
		{
			this.SendBytesAsync(session, HslProtocol.CommandBytes(customer, base.Token, bytes));
		}

		// Token: 0x0600157A RID: 5498 RVA: 0x0006F688 File Offset: 0x0006D888
		private void SendBytesAsync(AppSession session, byte[] data)
		{
			try
			{
				session.WorkSocket.SendTo(data, data.Length, SocketFlags.None, session.UdpEndPoint);
			}
			catch (Exception ex)
			{
				ILogNet logNet = base.LogNet;
				if (logNet != null)
				{
					logNet.WriteException("SendMessage", ex);
				}
			}
		}

		/// <summary>
		/// 当接收到文本数据的时候,触发此事件
		/// </summary>
		// Token: 0x14000033 RID: 51
		// (add) Token: 0x0600157B RID: 5499 RVA: 0x0006F6E0 File Offset: 0x0006D8E0
		// (remove) Token: 0x0600157C RID: 5500 RVA: 0x0006F718 File Offset: 0x0006D918
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event Action<AppSession, NetHandle, string> AcceptString;

		/// <summary>
		/// 当接收到字节数据的时候,触发此事件
		/// </summary>
		// Token: 0x14000034 RID: 52
		// (add) Token: 0x0600157D RID: 5501 RVA: 0x0006F750 File Offset: 0x0006D950
		// (remove) Token: 0x0600157E RID: 5502 RVA: 0x0006F788 File Offset: 0x0006D988
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event Action<AppSession, NetHandle, byte[]> AcceptByte;

		/// <inheritdoc />
		// Token: 0x0600157F RID: 5503 RVA: 0x0006F7BD File Offset: 0x0006D9BD
		public override string ToString()
		{
			return string.Format("NetUdpServer[{0}]", base.Port);
		}
	}
}
